package com.hyfrogx.modules.zoom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hyfrogx.common.exception.MyException;
import com.hyfrogx.common.log.LogEnum;
import com.hyfrogx.common.log.LogUtils;
import com.hyfrogx.common.utils.AppPushParam;
import com.hyfrogx.common.utils.QueryExt;
import com.hyfrogx.common.utils.RedisUtils;
import com.hyfrogx.config.ZoomConfig;
import com.hyfrogx.modules.app.utils.FrogConstant;
import com.hyfrogx.modules.app.utils.StringUtils;
import com.hyfrogx.modules.operation.dao.HyAppPushDao;
import com.hyfrogx.modules.operation.entity.HyAppPushEntity;
import com.hyfrogx.modules.operation.service.umeng.UmengService;
import com.hyfrogx.modules.zoom.dao.HyZoomMeetingDao;
import com.hyfrogx.modules.zoom.entity.HyZoomMeeting;
import com.hyfrogx.modules.zoom.entity.HyZoomVipUserEntity;
import com.hyfrogx.modules.zoom.param.MeetpriceType;
import com.hyfrogx.modules.zoom.service.*;
import com.hyfrogx.modules.zoom.utils.MyThreadUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;

/**
 * @author ：Li9527
 * @date ：Created in 2019-03-27 11:00
 * @description：会议室业务Service
 * @modified By：
 * @version: 1.0
 */
@Service("HyZoomMeetingService")
@Slf4j
public class HyZoomMeetingServiceImpl extends ServiceImpl<HyZoomMeetingDao, HyZoomMeeting> implements HyZoomMeetingService {

    @Autowired
    HyZoomMeetingDao mettingDao;

    @Autowired
    ZoomConfig zoomConfig;

    @Autowired
    HyZoomUserService zoomUserService;

    @Autowired
    UmengService umengService;

    @Autowired
    HyZoomVipUserService zoomVipUserService;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    MeetPriceService meetPriceService;

    @Autowired
    MeetJoinPriceService meetJoinPriceService;

    @Autowired
    HyAppPushDao appPushDao;

    private Logger ZOOM_LOGS = LogUtils.Logger(LogEnum.ZOOM_LOGS);

    @Override
    public Page selectPageByConditions(QueryExt query) {
        Map map = new HashMap();
        map.putAll(query.getCondition());
        query.setRecords(mettingDao.selectPageByConditions(query, map));
        return query;
    }

    @Override
    public HyZoomMeeting openMeetZoom(HyZoomMeeting hyZoomMeeting) {
        // 删除该上一场会议
        this.deleteMeetZoom(hyZoomMeeting);
        //删除后重建会议室
        HyZoomMeeting meeting = this.reBuildMeetZoom(hyZoomMeeting);
        //获取token,注入预留字段
        String token = zoomUserService.getusertoken(hyZoomMeeting.getHostid());
        //获取zak,注入zak字段
        String zak = zoomUserService.getuserZak(hyZoomMeeting.getHostid());
        if (zak != null) {
            meeting.setZak(zak);
        }
        if (token != null) {
            meeting.setToken(token);
        }
        //倒计时线程开始,测试阶段30分钟后结束,测试通过修改成4小时,注意只有非专属会议室才开启线程计时
        if (meeting.getIsvipzoom() != 1) {
            MyThreadUtils threadUtils = new MyThreadUtils(meeting, this);
            threadUtils.start(meeting, this);
        }
        return meeting;
    }

    @Override
    public Integer closeMeetZoom(HyZoomMeeting hyZoomMeeting) {
        ZOOM_LOGS.info("已开始通过线程到达指定时间开始结束一场会议，会议id为" + hyZoomMeeting.getZoomid());
        //接入参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("id", hyZoomMeeting.getZoomid().toString()));
        params.add(new BasicNameValuePair("host_id", hyZoomMeeting.getHostid()));
        params.add(new BasicNameValuePair("api_key", zoomConfig.getApi_key()));
        params.add(new BasicNameValuePair("api_secret", zoomConfig.getApi_secret()));
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost("https://www.zoomus.cn/v1/meeting/end");
        CloseableHttpResponse response = null;
        try {
            // 加浏览器头防止被过滤
            post.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT5.1; en-US; rv:0.9.4)");
            post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
            response = httpclient.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = response.getEntity();
                if (null != httpEntity) {
                    String retSrc = EntityUtils.toString(httpEntity);
                    ZOOM_LOGS.info(retSrc);
                    //修改会议室使用状态为空闲
                    hyZoomMeeting.setMeetstatus(0);
                    int result = mettingDao.updateById(hyZoomMeeting);
                    return result;
                }
            }
        } catch (Exception e) {
            throw new MyException(e.getMessage());
        }
        return -1;
    }

    @Override
    public int deleteMeetZoom(HyZoomMeeting hyZoomMeeting) {
        //接入参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("id", hyZoomMeeting.getZoomid().toString()));
        params.add(new BasicNameValuePair("host_id", hyZoomMeeting.getHostid()));
        params.add(new BasicNameValuePair("api_key", zoomConfig.getApi_key()));
        params.add(new BasicNameValuePair("api_secret", zoomConfig.getApi_secret()));
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost("https://www.zoomus.cn/v1/meeting/delete");
        CloseableHttpResponse response = null;
        try {
            // 加浏览器头防止被过滤
            post.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT5.1; en-US; rv:0.9.4)");
            post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
            response = httpclient.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = response.getEntity();
                if (null != httpEntity) {
                    String retSrc = EntityUtils.toString(httpEntity);
                    System.out.println(retSrc);
                }
            }
        } catch (Exception e) {
            throw new MyException(e.getMessage());
        }
        return response.getStatusLine().getStatusCode();
    }

    @Override
    public int createMeetZoom(HyZoomMeeting hyZoomMeeting) throws Exception {
        //java获取utc时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
        Date date = calendar.getTime();
        //接入参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("host_id", hyZoomMeeting.getHostid()));
        params.add(new BasicNameValuePair("api_key", zoomConfig.getApi_key()));
        params.add(new BasicNameValuePair("api_secret", zoomConfig.getApi_secret()));
        params.add(new BasicNameValuePair("topic", "会议室主题"));
        params.add(new BasicNameValuePair("type", "2"));
        params.add(new BasicNameValuePair("start_time", date.toString()));
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost("https://www.zoomus.cn/v1/meeting/create");
        CloseableHttpResponse response = null;
        try {
            // 加浏览器头防止被过滤
            post.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT5.1; en-US; rv:0.9.4)");
            post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
            response = httpclient.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = response.getEntity();
                if (null != httpEntity) {
                    String retSrc = EntityUtils.toString(httpEntity);
                    //普通会议室获取回调进行数据持久化
                    JSONObject jsonObject = new JSONObject(retSrc);
                    //会议室默认名称
                    hyZoomMeeting.setLocalname(jsonObject.getString("topic"));
                    //会议室Id,每次开会都会重新创建被覆盖
                    hyZoomMeeting.setZoomid(jsonObject.getInt("id"));
                    //会议开启Url/需覆盖
                    hyZoomMeeting.setStarturl(jsonObject.getString("start_url"));
                    //会议加入Url/需覆盖
                    hyZoomMeeting.setJoinurl(jsonObject.getString("join_url"));
                    //是否有密码/1有0没有 默认没有
                    hyZoomMeeting.setIshavepsd(0);
                    //是否专属会议室  0 公共/1 VIP专属 /2 免费体验
                    hyZoomMeeting.setIsvipzoom(1);
                    //当前会议状态: 0空闲1使用中
                    hyZoomMeeting.setMeetstatus(0);
                    //web端展示状态 0隐藏1展示<针对公共房间>让web可控制客户端房间显示及隐藏
                    hyZoomMeeting.setShowstatus(1);
                    //真实是否可用状态 0不可用1可用
                    hyZoomMeeting.setTruestatus(1);
                    //创建时间/初次创建时间
                    hyZoomMeeting.setCreateat(new Date());
                    //启用时间
                    hyZoomMeeting.setUpdateat(new Date());
                    //剩余天数,默认一年
                    hyZoomMeeting.setLaveday(365);
                    //设置会议外层id默认值
                    hyZoomMeeting.setHymeetid(String.valueOf(System.currentTimeMillis()));
                    int result = mettingDao.insert(hyZoomMeeting);
                    if (result > 0) {
                        // 设置第一个关联账号
                        HyZoomVipUserEntity entity = new HyZoomVipUserEntity();
                        entity.setZuid(hyZoomMeeting.getUid().intValue());
                        entity.setOuid(hyZoomMeeting.getUid().intValue());
                        entity.setOperatorUid(1);
                        entity.setZid(hyZoomMeeting.getId());
                        entity.setStatu(FrogConstant.BasicStatus.TRUE.getValue());
                        zoomVipUserService.add(entity);
                        return result;
                    } else {
                        return 0;
                    }
                }
            }
        } catch (MyException e) {
            throw new MyException(e.getMessage());
        }
        return 0;
    }

    @Override
    public HyZoomMeeting reBuildMeetZoom(HyZoomMeeting hyZoomMeeting) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
        Date date = calendar.getTime();
        //接入参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("host_id", hyZoomMeeting.getHostid()));
        params.add(new BasicNameValuePair("api_key", zoomConfig.getApi_key()));
        params.add(new BasicNameValuePair("api_secret", zoomConfig.getApi_secret()));
        params.add(new BasicNameValuePair("topic", hyZoomMeeting.getLocalname()));
        params.add(new BasicNameValuePair("type", "2"));
        params.add(new BasicNameValuePair("start_time", date.toString()));
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost("https://www.zoomus.cn/v1/meeting/create");
        CloseableHttpResponse response = null;
        try {
            // 加浏览器头防止被过滤
            post.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT5.1; en-US; rv:0.9.4)");
            post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
            response = httpclient.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = response.getEntity();
                if (null != httpEntity) {
                    String retSrc = EntityUtils.toString(httpEntity);
                    //普通会议室获取回调进行数据持久化
                    JSONObject jsonObject = new JSONObject(retSrc);
                    //会议室Id,每次开会都会重新创建被覆盖
                    hyZoomMeeting.setZoomid(jsonObject.getInt("id"));
                    //如果有密码
                    if (hyZoomMeeting.getPassword() != null && StringUtils.isNotBlank(hyZoomMeeting.getPassword())) {
                        hyZoomMeeting.setIshavepsd(1);
                    } else {
                        // 如果没有密码
                        hyZoomMeeting.setIshavepsd(0);
                    }
                    //如果有收费
                    if (hyZoomMeeting.getPrice() > 0) {
                        hyZoomMeeting.setIscharge(1);
                    } else {
                        hyZoomMeeting.setIscharge(0);
                    }
                    //会议开启Url/需覆盖
                    hyZoomMeeting.setStarturl(jsonObject.getString("start_url"));
                    //会议加入Url/需覆盖
                    hyZoomMeeting.setJoinurl(jsonObject.getString("join_url"));
                    //当前会议状态: 0空闲1使用中
                    hyZoomMeeting.setMeetstatus(1);
                    int result = mettingDao.updateById(hyZoomMeeting);
                    HyZoomMeeting zoomMetting = mettingDao.selectById(hyZoomMeeting.getId());
                    if (result > 0) {
                        return zoomMetting;
                    } else {
                        return zoomMetting;
                    }
                } else {
                    hyZoomMeeting.setMeetstatus(0);
                    int result = mettingDao.updateById(hyZoomMeeting);
                }
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return hyZoomMeeting;
    }

    @Override
    public void checkHaveNeedCloseZoom() throws MyException {
        // 获取专属会议室列表
        Map<String, Object> params = new HashMap<>();
        params.put("orderByField", "id");
        params.put("isAsc", false);
        params.put("isvipzoom", 1);
        // 要关联查询专属名称、参会标记、所属账号【手机号】、附加账号数量、创建时间，启用时间、到期时间、
        Page page = this.selectPageByConditions(new QueryExt<>(params));
        if(page.getRecords().size() > 0){
            List<HyZoomMeeting> list = page.getRecords();
            for (int i = 0; i < list.size(); i++) {
                // 查询当前时间是否大于了会议室到期时间
                if(System.currentTimeMillis() > list.get(i).getEndat().getTime()){
                    // 已过期,删除Zoom账号,把会议室置为无效用户不能拉取<账号已删除,无法再次使用>,但是保留所有开会记录
                    ZOOM_LOGS.info("删除账号---:" + list.get(i).getHostid() + "会议室主键id为" + list.get(i).getId());
                    zoomUserService.deleteZoomUser(list.get(i).getHostid());
                    // 删除一对多关系表
                    zoomVipUserService.remove(new QueryWrapper<HyZoomVipUserEntity>().eq("zid", list.get(i).getId()));
                    list.get(i).setTruestatus(0);
                    this.updateById(list.get(i));
                }
            }
        }
    }

    @Override
    public Integer getTrueStatusFromZoom(HyZoomMeeting zoomMeeting) {
        // 接入参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("host_id", zoomMeeting.getHostid()));
        params.add(new BasicNameValuePair("api_key", zoomConfig.getApi_key()));
        params.add(new BasicNameValuePair("api_secret", zoomConfig.getApi_secret()));
        params.add(new BasicNameValuePair("id", zoomMeeting.getZoomid().toString()));
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost("https://www.zoomus.cn/v1/meeting/get");
        CloseableHttpResponse response = null;
        try {
            Integer flag = -1;
            // 加浏览器头防止被过滤
            post.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT5.1; en-US; rv:0.9.4)");
            post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
            response = httpclient.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = response.getEntity();
                if (null != httpEntity) {
                    String retSrc = EntityUtils.toString(httpEntity);
                    // 普通会议室获取回调进行数据持久化
                    JSONObject jsonObject = new JSONObject(retSrc);
                    // 会议室Id,每次开会都会重新创建被覆盖
                    flag = jsonObject.getInt("status");
                    return flag;
                }
            }
        } catch (Exception e) {
            throw new MyException(e.getMessage());
        }
        return -1;
    }

    @Override
    public boolean doPush(HyAppPushEntity appPush) throws Exception {
        boolean result = umengService.singleBroadcastByMeetWillEnd(appPush);
        return result;
    }

    @Override
    public Page selectZoomMeeting(QueryExt query) {
        Map map = new HashMap();
        map.putAll(query.getCondition());
        query.setRecords(mettingDao.selectZoomMeeting(query, map));
        return query;
    }

    @Override
    public void willExpire() throws Exception {
        // 获取专属会议室列表
        Map<String, Object> params = new HashMap<>();
        params.put("orderByField", "id");
        params.put("isAsc", false);
        params.put("isvipzoom", 1);
        // 要关联查询专属名称、参会标记、所属账号【手机号】、附加账号数量、创建时间，启用时间、到期时间、
        Page page = this.selectPageByConditions(new QueryExt<>(params));
        if(page.getRecords().size() > 0){
            List<HyZoomMeeting> list = page.getRecords();
            Long distant;
            // 发送推送
            HyAppPushEntity appPush = new HyAppPushEntity();
            //推送对象设置为用户自定义
            appPush.setAfterOpen(1);
            //推送消息类型为账号续费提醒
            appPush.setAppMessageType(3);
            appPush.setTitle("账号续费提醒");
            //即时
            appPush.setType(AppPushParam.AppPushType.current);
            // 推送范围，0全部，1个体
            appPush.setDisplayRange(1);
            appPush.setCustomAfterOpen(FrogConstant.CustomAfterOpen.go_my_zoom.getValue());

            /*Boolean pushr = zoomMeetingService.doPush(appPush);*/
            for (int i = 0; i < list.size(); i++) {
                Object token = redisUtils.getMap(FrogConstant.RedisKey.DEVICE_TOKEN).get(list.get(i).getUid().toString());
                if( token!= null) {
                    // 当前离到期时间的时间差以天为单位
                    distant = (list.get(i).getEndat().getTime() - System.currentTimeMillis()) / 1000 / 60 / 60 / 24;
                    appPush.setPhone(list.get(i).getPhone());
                    appPush.setDisplayStatus(AppPushParam.AppPushStatus.send_success);
                    appPush.setUid(0l);
                    appPush.setStartTime(new Date());
                    // 查询当前时间是否大于6天小于等于7天/7天内到期
                    if (distant > 6 && distant <= 7) {
                        appPush.setText("尊敬的用户，截止当前时间您的专属会议室"+list.get(i).getZoomname()+"还有7天到期，为了不影响您的使用，请尽快安排续费。如有疑问请联系客服。");
                        umengService.sendSingleBroadcast(appPush);
                    }
                    if (distant > 2 && distant <= 3) {
                        appPush.setText("尊敬的用户，截止当前时间您的专属会议室"+list.get(i).getZoomname()+"还有3天到期，为了不影响您的使用，请尽快安排续费。如有疑问请联系客服。");
                        umengService.sendSingleBroadcast(appPush);
                    }
                    if (distant > 0 && distant <= 1) {
                        appPush.setText("尊敬的用户，截止当前时间您的专属会议室"+list.get(i).getZoomname()+"还有1天到期，为了不影响您的使用，请尽快安排续费。如有疑问请联系客服。");
                        umengService.sendSingleBroadcast(appPush);
                    }
                }
            }
        }
    }

    @Override
    public Integer getNeedpay(HyZoomMeeting metting) throws MyException {
        String flag = "";
        if (metting.getMeetingcapacity().equals(25)) {
            flag = "a";
        } else if (metting.getMeetingcapacity().equals(50)) {
            flag = "b";
        } else if (metting.getMeetingcapacity().equals(100)) {
            flag = "c";
        } else if (metting.getMeetingcapacity().equals(200)) {
            flag = "e";
        } else if (metting.getMeetingcapacity().equals(300)) {
            flag = "f";
        } else if (metting.getMeetingcapacity().equals(500)) {
            flag = "d";
        } else {
            throw new MyException("配置丢失");
        }
        String quantity = flag + "_" + metting.getTime().toString();
        // 匹配枚举值,获取出该规模该时间长短下的会议金额对象属性,获取该属性收费金额
        String field = MeetpriceType.valueOf(quantity).getField();
        Integer needPay = meetPriceService.getMeetPriceByTime(field);
        return needPay;
    }

    @Override
    public Integer getJoinBasicMeetNeedpay(HyZoomMeeting metting) throws MyException {
        String flag = "";
        if (metting.getMeetingcapacity().equals(25)) {
            flag = "a";
        } else if (metting.getMeetingcapacity().equals(50)) {
            flag = "b";
        } else if (metting.getMeetingcapacity().equals(100)) {
            flag = "c";
        } else if (metting.getMeetingcapacity().equals(200)) {
            flag = "e";
        } else if (metting.getMeetingcapacity().equals(300)) {
            flag = "f";
        } else if (metting.getMeetingcapacity().equals(500)) {
            flag = "d";
        } else {
            throw new MyException("配置丢失");
        }
        String quantity = flag + "_" + metting.getTime().toString();
        // 匹配枚举值,获取出该规模该时间长短下的会议金额对象属性,获取该属性收费金额
        String field = MeetpriceType.valueOf(quantity).getField();
        Integer needPay = meetJoinPriceService.getMeetPriceByTime(field);
        return needPay;
    }
}
